<!DOCTYPE html>
<html lang="en">
	<head>
		<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
		<meta charset="UTF-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>使用 HTML、CSS 和 JavaScript 制作模拟时钟(初学者教程)</title>

		<style>
			body {
				background: rgb(13, 186, 230);
				color: #333;
				margin-top: 50px;
				font-family: Helvetica, sans-serif;
			}

			ul {
				list-style: none;
				top: 0;
				margin: 0;
				padding: 0;
				position: absolute;
				text-align: center;
			}

			li {
				position: absolute;
				transform-origin: 50% 100%;
				height: 160px;
				/* outline: #FF0000 1px solid; */
			}

			.hours {
				left: 120px;
				font-size: 23.3333333333px;
				letter-spacing: -1.6px;
				line-height: 45px;
			}

			.hours li {
				width: 80px;
			}

			.hours span {
				display: block;
			}

			.hours li:nth-of-type(1) {
				transform: rotate(30deg);
			}

			.hours li:nth-of-type(1) span {
				transform: rotate(-30deg);
			}

			.hours li:nth-of-type(2) {
				transform: rotate(60deg);
			}

			.hours li:nth-of-type(2) span {
				transform: rotate(-60deg);
			}

			.hours li:nth-of-type(3) {
				transform: rotate(90deg);
			}

			.hours li:nth-of-type(3) span {
				transform: rotate(-90deg);
			}

			.hours li:nth-of-type(4) {
				transform: rotate(120deg);
			}

			.hours li:nth-of-type(4) span {
				transform: rotate(-120deg);
			}

			.hours li:nth-of-type(5) {
				transform: rotate(150deg);
			}

			.hours li:nth-of-type(5) span {
				transform: rotate(-150deg);
			}

			.hours li:nth-of-type(6) {
				transform: rotate(180deg);
			}

			.hours li:nth-of-type(6) span {
				transform: rotate(-180deg);
			}

			.hours li:nth-of-type(7) {
				transform: rotate(210deg);
			}

			.hours li:nth-of-type(7) span {
				transform: rotate(-210deg);
			}

			.hours li:nth-of-type(8) {
				transform: rotate(240deg);
			}

			.hours li:nth-of-type(8) span {
				transform: rotate(-240deg);
			}

			.hours li:nth-of-type(9) {
				transform: rotate(270deg);
			}

			.hours li:nth-of-type(9) span {
				transform: rotate(-270deg);
			}

			.hours li:nth-of-type(10) {
				transform: rotate(300deg);
			}

			.hours li:nth-of-type(10) span {
				transform: rotate(-300deg);
			}

			.hours li:nth-of-type(11) {
				transform: rotate(330deg);
			}

			.hours li:nth-of-type(11) span {
				transform: rotate(-330deg);
			}

			.hours li:nth-of-type(12) {
				transform: rotate(360deg);
			}

			.hours li:nth-of-type(12) span {
				transform: rotate(-360deg);
			}


			#clock {
				background: #fff;
				border: 15px solid #222;
				border-radius: 50%;
				position: relative;
				width: 320px;
				height: 320px;
				margin: auto;
			}

			/* JavaScript pre-rotates these wrappers instead of the hands when getting the time at load. If it pre-rotates the hands, then the hands will not perform 1 turn at their normal speeds. */
			.hr-wrapper,
			.min-wrapper,
			.sec-wrapper {
				position: absolute;
				width: 320px;
				height: 320px;
			}

			.hand {
				position: absolute;
				bottom: 50%;
				transform-origin: 50% 100%;
			}

			.hr {
				background: #222;
				left: 152px;
				width: 13px;
				height: 105px;
				border-radius: 10px;
				animation: rotateHand 43200s linear infinite;
			}

			.hr:after {
				background: #222;
				border-radius: 50%;
				content: "";
				display: block;
				position: absolute;
				bottom: -8px;
				width: 13px;
				height: 16px;
			}

			.min {
				background: #222;
				left: 155px;
				width: 9px;
				height: 125px;
				border-radius: 8px;
				animation: rotateHand 3600s linear infinite;
			}

			.min:after {
				background: #222;
				border-radius: 50%;
				content: "";
				display: block;
				position: absolute;
				bottom: -8px;
				width: 9px;
				height: 16px;
			}

			.sec {
				background: #d00;
				left: 156.5px;
				width: 5px;
				height: 132px;
				border-radius: 8px;
				animation: rotateHand 60s linear infinite;
			}

			.sec:after {
				background: #d00;
				border-radius: 50%;
				content: "";
				display: block;
				position: absolute;
				bottom: -3.5px;
				width: 5px;
				height: 7px;
			}

			@keyframes rotateHand {
				to {
					transform: rotate(1turn);
				}
			}
		</style>
	</head>
	<body>
		<div id='clock'>
			<ul class='hours'>
				<li>
					<span>
						1
					</span>
				</li>
				<li>
					<span>
						2
					</span>
				</li>
				<li>
					<span>
						3
					</span>
				</li>
				<li>
					<span>
						4
					</span>
				</li>
				<li>
					<span>
						5
					</span>
				</li>
				<li>
					<span>
						6
					</span>
				</li>
				<li>
					<span>
						7
					</span>
				</li>
				<li>
					<span>
						8
					</span>
				</li>
				<li>
					<span>
						9
					</span>
				</li>
				<li>
					<span>
						10
					</span>
				</li>
				<li>
					<span>
						11
					</span>
				</li>
				<li>
					<span>
						12
					</span>
				</li>
			</ul>

			<div class='hr-wrapper'>
				<div class='hand hr'></div>
			</div>
			<div class='min-wrapper'>
				<div class='hand min'></div>
			</div>
			<div class='sec-wrapper'>
				<div class='hand sec'></div>
			</div>
		</div>

		<script>
			// get current time
			var dateInfo = new Date();
			var hr = dateInfo.getHours() > 12 ? dateInfo.getHours() - 12 : dateInfo.getHours(),
				min = dateInfo.getMinutes(),
				sec = dateInfo.getSeconds(),
				milsec = dateInfo.getMilliseconds();

			/*
			1 hr = 30°, 1 min = 6°, 1 sec = 6°, 1 millisec = 0.36°
			Even though we can calculate the proper angles of the hour, minute, and second hands, we can determine more accurately where the hands are between the current and next ticks. For example, if it is 6:30, we know that the hour hand is at least 180°, yet it should be between the 6 and 7. To get that, we divide the angle of the current minute by 12 ((30 * 6°) / 12) and add the result (15) to 180. Therefore, the hour hand should be at 195°.
			*/
			var hrAngle = hr * 30 + (min * 6 / 12),
				minAngle = min * 6 + (sec * 6 / 60),
				secAngle = sec * 6 + (milsec * 0.36 / 1000);

			// set initial angles of the hand wrappers
			function setAngle(wrapper, angle) {
				document.querySelector("." + wrapper).style.transform = "rotate(" + angle + "deg)";
			}
			setAngle("hr-wrapper", hrAngle);
			setAngle("min-wrapper", minAngle);
			setAngle("sec-wrapper", secAngle);
		</script>
	</body>
</html>
